package com.anche.cywebnew.Utils.HikUtil;

import com.anche.cywebnew.DAO.configManager.SysOptionMapper;
import com.anche.cywebnew.DAO.securityManager.VideoExceptionLogMapper;
import com.anche.cywebnew.Pojo.securityManager.VideoExceptionLog;
import com.anche.cywebnew.Utils.Spring.SpringBeanFactoryUtils;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class FMSGCallBack implements HCNetSDK.FMSGCallBack {

    private static final Logger logger = LoggerFactory.getLogger(FMSGCallBack.class);

    private VideoExceptionLogMapper videoExceptionLogMapper;

    public FMSGCallBack() {
        videoExceptionLogMapper = (VideoExceptionLogMapper) SpringBeanFactoryUtils.getBean(VideoExceptionLogMapper.class);
    }

    //报警信息回调函数
    private int flg = 0;

    Map<String, String> map = new HashMap<>();


    public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer,
                       HCNetSDK.RECV_ALARM pAlarmInfo, int dwBufLen, Pointer pUser) {
        String sAlarmType = new String();
        String[] newRow = new String[3];
        // 报警时间
        Date today = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String[] sIP = new String[2];
        short port;
        // lCommand是传的报警类型
        logger.info("HCNetSDK.COMM_ALARM_V30" + HCNetSDK.COMM_ALARM_V30);
        switch (lCommand.intValue()) {
            // 9000报警NET_DVR_ALARMOUTSTATUS_V30
            case HCNetSDK.COMM_ALARM_V30:
                HCNetSDK.NET_DVR_ALARMINFO_V30 strAlarmInfoV30 = new HCNetSDK.NET_DVR_ALARMINFO_V30();
                strAlarmInfoV30.write();
                Pointer pInfoV30 = strAlarmInfoV30.getPointer();
                pInfoV30.write(0, pAlarmInfo.RecvBuffer, 0, strAlarmInfoV30.size());
                strAlarmInfoV30.read();
                switch (strAlarmInfoV30.dwAlarmType) {
                    case 0:
                        sAlarmType = new String("信号量报警");
                        break;
                    case 1:
                        sAlarmType = new String("硬盘满");
                        break;
                    case 2:
                        sAlarmType = new String("信号丢失");
                        break;
                    case 3:
                        sAlarmType = new String("移动侦测");
                        break;
                    case 4:
                        sAlarmType = new String("硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = new String("读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = new String("遮挡报警");
                        break;
                    case 7:
                        sAlarmType = new String("制式不匹配");
                        break;
                    case 8:
                        sAlarmType = new String("非法访问");
                        break;
                }
                //报警时间
                newRow[0] = dateFormat.format(today);
                // 报警类型
                newRow[1] = sAlarmType;
                // 报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                port = pAlarmer.wLinkPort;
                newRow[2] = sIP[0];
                flg++;
                byte[] chByte = strAlarmInfoV30.byChannel;
                if (flg == 1) {
                    for (int i = 0; i < chByte.length; i++) {
                        if (chByte[i] == 1) {
                            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                            map.put(newRow[2] + ":" + port + ":" + i + 1, uuid);
                            VideoExceptionLog videoExceptionLog = new VideoExceptionLog(uuid,
                                    newRow[2], String.valueOf(port), String.valueOf(i + 1), newRow[1], new Date(), String.valueOf(flg));
                            videoExceptionLogMapper.insertVideoException(videoExceptionLog);
                        }
                    }
                } else {
                    for (int i = 0; i < chByte.length; i++) {
                        if (chByte[i] == 1) {
                            String uuid = map.get(newRow[2] + ":" + port + ":" + i + 1);
                            VideoExceptionLog videoExceptionLog = new VideoExceptionLog(uuid, new Date(), String.valueOf(flg));
                            videoExceptionLogMapper.updateById(videoExceptionLog);
                        }
                    }
                }
                logger.info("报警时间：[{}];报警类型:[{}];报警IP地址：[{}];报警个数[{}]", newRow[0], newRow[1], newRow[2], flg);
                break;

            // 8000报警
            case HCNetSDK.COMM_ALARM:
                HCNetSDK.NET_DVR_ALARMINFO strAlarmInfo = new HCNetSDK.NET_DVR_ALARMINFO();
                strAlarmInfo.write();
                Pointer pInfo = strAlarmInfo.getPointer();
                pInfo.write(0, pAlarmInfo.RecvBuffer, 0, strAlarmInfo.size());
                strAlarmInfo.read();

                switch (strAlarmInfo.dwAlarmType) {
                    case 0:
                        sAlarmType = new String("信号量报警");
                        break;
                    case 1:
                        sAlarmType = new String("硬盘满");
                        break;
                    case 2:
                        sAlarmType = new String("信号丢失");
                        break;
                    case 3:
                        sAlarmType = new String("移动侦测");
                        break;
                    case 4:
                        sAlarmType = new String("硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = new String("读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = new String("遮挡报警");
                        break;
                    case 7:
                        sAlarmType = new String("制式不匹配");
                        break;
                    case 8:
                        sAlarmType = new String("非法访问");
                        break;
                }

                newRow[0] = dateFormat.format(today);
                // 报警类型
                newRow[1] = sAlarmType;
                // 报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                flg++;
                logger.info("报警时间：[{}];报警类型:[{}];报警IP地址：[{}];报警个数[{}]", newRow[0], newRow[1], newRow[2], flg);
                break;

            // ATM DVR transaction information
            case HCNetSDK.COMM_TRADEINFO:
                // 处理交易信息报警
                break;

            // IPC接入配置改变报警
            case HCNetSDK.COMM_IPCCFG:
                // 处理IPC报警
                break;

            default:
                System.out.println("未知报警类型");
                break;
        }
    }
}
